package com.googlecode.animator.view.timeline
{
	import com.googlecode.animator.data.Notifications;
	import com.googlecode.data.markers.GlobalMarkerVO;
	import com.googlecode.data.markers.HideMarkerVO;
	import com.googlecode.data.markers.KeyframeVO;
	import com.googlecode.data.objects3d.CameraProxyVO;
	import com.googlecode.data.objects3d.Object3DVO;
	import com.googlecode.data.objects3d.TargetProxyVO;
	import com.googlecode.animator.model.ProjectSettingsProxy;
	
	import flash.events.MouseEvent;
	import flash.utils.Dictionary;
	
	import mx.controls.CheckBox;
	
	import org.papervision3d.core.math.Number3D;
	import org.puremvc.as3.multicore.interfaces.IProxy;
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;

	/**
	 * Ties the TransportControls component in with the PureMVC framework 
	 * @author USER
	 * 
	 */
	public class TransportControlsMediator extends Mediator
	{
		/**
		 * Identifier. 
		 */
		public static const NAME:String = "transportControls";
		
		
		/**
		 * Constructor. 
		 * @param mediatorName
		 * @param viewComponent
		 * 
		 */
		public function TransportControlsMediator(viewComponent:TransportControls)
		{
			super(NAME, viewComponent);
		}
		
		/**
		 * Called by PureMVC framework. 
		 * 
		 */
		override public function onRegister():void
		{
			super.onRegister();
			
			viewRef.addEventListener(MouseEvent.CLICK, onTransportControls);
			
		}
		
		/**
		 * Clean up. 
		 * 
		 */
		override public function onRemove():void
		{
			super.onRemove();
			
			viewRef.removeEventListener(MouseEvent.CLICK, onTransportControls);
		}
		
		/**
		 * All user input to transport controls is handled here. 
		 * @param evt
		 * 
		 */
		protected function onTransportControls(evt:MouseEvent):void
		{
			switch(evt.target.name)
			{
				case TransportControls.GLOBAL_MARKER:
				
					handleGlobalMarker();
					
					break;
				case TransportControls.POSITION_KEYFRAME:
					
					handlePositionKeyframe();
					
					break;
				case TransportControls.HIDE_MARKER:
					
					handleHideMarker();
					
					break;
				case TransportControls.EXTEND_TIMELINE:
				
					sendNotification(Notifications.TIMELINE_EXTEND);
					
					break;
					
				case TransportControls.AUTO_KEYFAMING:
				
					handleAutoKeyframing();
					
					break;
			}
		}
		
		protected function handleGlobalMarker():void
		{
			var globalMarkers:Dictionary = settings.globalMarkers;
			
			for each(var gm:GlobalMarkerVO in globalMarkers)
			{
				if(settings.currentTimeInterval == gm.time)
				{
					return;
				}
			}
			
			gm = new GlobalMarkerVO();
			
			gm.time = settings.currentTimeInterval;
			
			sendNotification(Notifications.ADD_GLOBAL_MARKER, gm);
		}
		
		/**
		 * Responds to a user generated request to add a keyframe. 
		 * 
		 */
		protected function handlePositionKeyframe():void
		{
			
			var selName:String = settings.selectedObject3D;
			
			if(selName != null)
			{
				var VO:Object3DVO = settings.getObject3D(selName);
				var keyframes:Dictionary = VO.keyframes;
				var time:uint = settings.currentTimeInterval;
				
				// abandon if keyframe already present at that time interval
				for each(var kf:KeyframeVO in keyframes)
				{
					if(kf.time == time)
					{
						return;
					}
				}
				
				var position:Number3D = settings.getPosObject3DInScene(VO.name);
				
				kf = new KeyframeVO();
				kf.position = position;
				kf.time = time;
				kf.object3DName = VO.name;
				
				sendNotification(Notifications.TIMELINE_ADD_KEYFRAME, kf);
			}
			
			
		}
		
		/**
		 * Responds to a user generated request to add a hide marker. 
		 * 
		 */
		protected function handleHideMarker():void
		{
			
			var selName:String = settings.selectedObject3D;
			
			if(selName != null)
			{
				var VO:Object3DVO = settings.getObject3D(selName);
				
				// hide markers should not be added to CameraProxy or TargetProxy
				if(VO is CameraProxyVO || VO is TargetProxyVO)
				{
					return;
				}
				
				var time:uint = settings.currentTimeInterval;
				var hideMarkers:Dictionary = VO.hideMarkers;
				
				// check that a hidemarker does not already exist
				for each(var hm:HideMarkerVO in hideMarkers)
				{
					
					if(hm.begin <= time && hm.end >= time)
					{
						return;
					}
				}
				
				hm = new HideMarkerVO();
				hm.begin = time;
				hm.end = time;

				hm.object3DName = VO.name;
				
				sendNotification(Notifications.TIMELINE_ADD_HIDE_MARKER, hm);
			}
			
			
		}
		
		/**
		 * Determines whether auto keyframing is enabled or not. 
		 * 
		 */
		protected function handleAutoKeyframing():void
		{
			if((viewRef.getChildByName(TransportControls.AUTO_KEYFAMING) as CheckBox).selected )
			{
				sendNotification(Notifications.TIMELINE_AUTO_KEYFRAMING, true);
			}else
			{
				sendNotification(Notifications.TIMELINE_AUTO_KEYFRAMING, false);
			}
		}
		
		/**
		 * Returns typed reference to ProjectSettingsProxy. 
		 * @return 
		 * 
		 */
		protected function get settings():ProjectSettingsProxy
		{
			var proxy:IProxy = facade.retrieveProxy(ProjectSettingsProxy.NAME) as IProxy;
			
			return proxy as ProjectSettingsProxy;
		}
		
		/**
		 * Returns typed reference to component. 
		 * @return 
		 * 
		 */
		protected function get viewRef():TransportControls
		{
			return viewComponent as TransportControls;
		}
	}
}